<template>
  <div ref="wrapRef"></div>
</template>
<script lang="ts">
import type { Ref } from "vue";
import {
  defineComponent,
  ref,
  unref,
  nextTick,
  computed,
  watch,
  onBeforeUnmount,
  onDeactivated,
} from "vue";
import Vditor from "vditor";
import "vditor/dist/index.css";
import { useModalContext } from "../../Modal";
import { onMountedOrActivated } from "$/hooks/core/onMountedOrActivated";

export default defineComponent({
  inheritAttrs: false,
  props: {
    theme: { type: String, default: "classic" },
    height: { type: Number, default: 360 },
    value: { type: String, default: "" },
  },
  emits: ["change", "get", "update:value"],
  setup(props, { attrs, emit }) {
    const wrapRef = ref<ElRef>(null);
    const vditorRef = ref(null) as Ref<Nullable<Vditor>>;
    const initedRef = ref(false);

    const modalFn = useModalContext();

    const valueRef = ref(props.value || "");

    watch(
      [() => props.theme, () => initedRef.value],
      ([val, inited]) => {
        if (!inited) {
          return;
        }
        const theme = val === "dark" ? "dark" : "classic";
        instance.getVditor()?.setTheme(theme);
      },
      {
        immediate: true,
        flush: "post",
      }
    );

    watch(
      () => props.value,
      (v) => {
        if (v !== valueRef.value) {
          instance.getVditor()?.setValue(v);
        }
        valueRef.value = v;
      }
    );

    function init() {
      const wrapEl = unref(wrapRef) as HTMLElement;
      if (!wrapEl) return;
      const bindValue = { ...attrs, ...props };
      const insEditor = new Vditor(wrapEl, {
        lang: "zh_CN",
        theme: "classic",
        mode: "sv",
        fullscreen: {
          index: 520,
        },
        preview: {
          actions: [],
        },
        input: (v) => {
          valueRef.value = v;
          emit("update:value", v);
          emit("change", v);
        },
        after: () => {
          nextTick(() => {
            modalFn?.redoModalHeight?.();
            insEditor.setValue(valueRef.value);
            vditorRef.value = insEditor;
            initedRef.value = true;
            emit("get", instance);
          });
        },
        blur: () => {
          //unref(vditorRef)?.setValue(props.value);
        },
        ...bindValue,
        cache: {
          enable: false,
        },
      });
    }

    const instance = {
      getVditor: (): Vditor => vditorRef.value!,
    };

    function destroy() {
      const vditorInstance = unref(vditorRef);
      if (!vditorInstance) return;
      try {
        vditorInstance?.destroy?.();
      } catch (error) {}
      vditorRef.value = null;
      initedRef.value = false;
    }

    onMountedOrActivated(init);

    onBeforeUnmount(destroy);
    onDeactivated(destroy);
    return {
      wrapRef,
      ...instance,
    };
  },
});
</script>
